﻿package game.network.api.fb.net {

	import game.encrypt.PNGEncoder;
	import game.network.api.fb.core.FacebookURLDefaults;
	import game.network.api.fb.data.Batch;
	import game.network.api.fb.data.BatchItem;
	import game.network.api.fb.utils.PostRequest;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;

	public class FacebookBatchRequest extends AbstractFacebookRequest {

		protected var _params:Object;
		protected var _relativeURL:String;
		protected var _fileData:Object;
		protected var _accessToken:String;
		protected var _batch:Batch;

		public function FacebookBatchRequest (batch:Batch, completeCallback:Function = null) {
			_batch = batch;
			_callback = completeCallback;
		}

		public function call (accessToken:String):void {
			_accessToken = accessToken;

			urlRequest = new URLRequest(FacebookURLDefaults.GRAPH_URL);
			urlRequest.method = URLRequestMethod.POST;

			var formatted:Array = [];
			var files:Array = [];
			var hasFiles:Boolean = false;

			var requests:Array = _batch.requests;

			var l:uint = requests.length;
			for (var i:uint=0; i<l; i++) {
				var request:BatchItem = requests[i];
				var fileData:Object = this.extractFileData(request.params);
				var params:Object = {method:request.requestMethod,relative_url:request.relativeURL};

				if (request.params) {
					if (request.params['contentType'] != undefined) {
						params.contentType = request.params['contentType'];
					}
					var urlVars:String = this.objectToURLVariables(request.params).toString();
					if (request.requestMethod == URLRequestMethod.GET || request.requestMethod.toUpperCase() == "DELETE") {
						params.relative_url +=  "?" + urlVars;
					} else {
						params.body = urlVars;
					}
				}

				formatted.push (params);

				if (fileData) {
					files.push (fileData);
					params.attached_files = request.params.fileName == null ? 'file' + i:request.params.fileName;
					hasFiles = true;
				} else {
					files.push (null);
				}
			}

			if (! hasFiles) {
				var requestVars:URLVariables = new URLVariables();
				requestVars.access_token = accessToken;
				requestVars.batch = JSON.stringify(formatted);

				urlRequest.data = requestVars;

				loadURLLoader ();
			} else {
				sendPostRequest (formatted, files);
			}
		}

		protected function sendPostRequest (requests:Array, files:Array):void {
			var post:PostRequest = new PostRequest();
			post.writePostData ('access_token', _accessToken);
			post.writePostData ('batch', JSON.stringify(requests));

			var l:uint = requests.length;

			for (var i:uint=0; i<l; i++) {
				var values:Object = requests[i];

				var fileData:Object = files[i];
				if (fileData) {
					if (fileData is Bitmap) {
						fileData = (fileData as Bitmap).bitmapData;
					}

					if (fileData is ByteArray) {
						post.writeFileData (values.attached_files, fileData as ByteArray, values.contentType);
					} else if (fileData is BitmapData) {
						var ba:ByteArray = PNGEncoder.encode(fileData as BitmapData);
						post.writeFileData (values.attached_files, ba, 'image/png');
					}
				}
			}

			post.close ();

			urlRequest.contentType = 'multipart/form-data; boundary=' + post.boundary;
			urlRequest.data = post.getPostData();

			loadURLLoader ();
		}

		override protected function handleDataReady ():void {
			var results:Array = _data as Array;
			var l:uint = results.length;

			for (var i:uint=0; i<l; i++) {
				var body:Object = JSON.parse(_data[i].body);
				_data[i].body = body;

				if ((_batch.requests[i] as BatchItem).callback != null) {
					(_batch.requests[i] as BatchItem).callback (_data[i]);
				}
			}
		}
	}
}